From: Tim Deegan Date: Mon, 5 Feb 2007 11:38:22 +0000 (+0000) Subject: [HVM] Save/restore: misc tidying X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=12d64eed3d3b117f44af1f6927b21464513358fb;p=xen.git [HVM] Save/restore: misc tidying - Don't save PIT's last-load-time or CPU's vmx-assist bits - Reorder save as cpu, PICs, irqs, timers - Save the correct value in the HPET's counter. Signed-off-by: Tim Deegan --- diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c index dcc6ca3a4d..6269e149a8 100644 --- a/xen/arch/x86/hvm/hpet.c +++ b/xen/arch/x86/hvm/hpet.c @@ -383,6 +383,9 @@ static int hpet_save(struct domain *d, hvm_domain_context_t *h) { HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet; + /* Write the proper value into the main counter */ + hp->hpet.mc64 = hp->mc_offset + hvm_get_guest_time(hp->vcpu); + /* Save the HPET registers */ return hvm_save_entry(HPET, 0, h, &hp->hpet); } diff --git a/xen/arch/x86/hvm/i8254.c b/xen/arch/x86/hvm/i8254.c index 5473f914f4..11ae4ff0ca 100644 --- a/xen/arch/x86/hvm/i8254.c +++ b/xen/arch/x86/hvm/i8254.c @@ -83,8 +83,8 @@ static int pit_get_count(PITState *s, int channel) struct hvm_hw_pit_channel *c = &s->hw.channels[channel]; struct periodic_time *pt = &s->pt[channel]; - d = muldiv64(hvm_get_guest_time(pt->vcpu) - - c->count_load_time, PIT_FREQ, ticks_per_sec(pt->vcpu)); + d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel], + PIT_FREQ, ticks_per_sec(pt->vcpu)); switch(c->mode) { case 0: case 1: @@ -110,7 +110,7 @@ int pit_get_out(PITState *pit, int channel, int64_t current_time) uint64_t d; int out; - d = muldiv64(current_time - s->count_load_time, + d = muldiv64(current_time - pit->count_load_time[channel], PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu)); switch(s->mode) { default: @@ -153,7 +153,7 @@ void pit_set_gate(PITState *pit, int channel, int val) case 5: if (s->gate < val) { /* restart counting on rising edge */ - s->count_load_time = hvm_get_guest_time(pt->vcpu); + pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); // pit_irq_timer_update(s, s->count_load_time); } break; @@ -161,7 +161,7 @@ void pit_set_gate(PITState *pit, int channel, int val) case 3: if (s->gate < val) { /* restart counting on rising edge */ - s->count_load_time = hvm_get_guest_time(pt->vcpu); + pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); // pit_irq_timer_update(s, s->count_load_time); } /* XXX: disable/enable counting */ @@ -177,8 +177,8 @@ int pit_get_gate(PITState *pit, int channel) void pit_time_fired(struct vcpu *v, void *priv) { - struct hvm_hw_pit_channel *s = priv; - s->count_load_time = hvm_get_guest_time(v); + uint64_t *count_load_time = priv; + *count_load_time = hvm_get_guest_time(v); } static inline void pit_load_count(PITState *pit, int channel, int val) @@ -190,7 +190,7 @@ static inline void pit_load_count(PITState *pit, int channel, int val) if (val == 0) val = 0x10000; - s->count_load_time = hvm_get_guest_time(pt->vcpu); + pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); s->count = val; period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ); @@ -203,7 +203,7 @@ static inline void pit_load_count(PITState *pit, int channel, int val) val, period, s->mode, - (long long)s->count_load_time); + (long long)pit->count_load_time[channel]); #endif /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */ @@ -216,11 +216,13 @@ static inline void pit_load_count(PITState *pit, int channel, int val) switch (s->mode) { case 2: /* create periodic time */ - create_periodic_time(v, pt, period, 0, 0, pit_time_fired, s); + create_periodic_time(v, pt, period, 0, 0, pit_time_fired, + &pit->count_load_time[channel]); break; case 1: /* create one shot time */ - create_periodic_time(v, pt, period, 0, 1, pit_time_fired, s); + create_periodic_time(v, pt, period, 0, 1, pit_time_fired, + &pit->count_load_time[channel]); #ifdef DEBUG_PIT printk("HVM_PIT: create one shot time.\n"); #endif @@ -387,7 +389,7 @@ static void pit_info(PITState *pit) printk("pit 0x%x.\n", s->mode); printk("pit 0x%x.\n", s->bcd); printk("pit 0x%x.\n", s->gate); - printk("pit %"PRId64"\n", s->count_load_time); + printk("pit %"PRId64"\n", pit->count_load_time[i]); pt = &pit->pt[i]; if (pt) { diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index a35b84848d..76112e14ef 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -591,6 +591,7 @@ void svm_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data) { struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + vmcb->kerngsbase = data->shadow_gs; /* MSR_LSTAR, MSR_STAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_EFER */ vmcb->lstar = data->msr_items[0]; vmcb->star = data->msr_items[1]; diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 8a8691c383..0a4c008b37 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -588,7 +588,7 @@ void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data) int i = 0; data->shadow_gs = guest_state->shadow_gs; - data->vmxassist_enabled = v->arch.hvm_vmx.vmxassist_enabled; + /* save msrs */ data->flags = guest_flags; for (i = 0; i < VMX_MSR_COUNT; i++) @@ -611,10 +611,7 @@ void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data) guest_state->shadow_gs = data->shadow_gs; - /*XXX:no need to restore msrs, current!=vcpu as not called by arch_vmx_do_launch */ -/* vmx_restore_guest_msrs(v);*/ - - v->arch.hvm_vmx.vmxassist_enabled = data->vmxassist_enabled; + v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE); hvm_set_guest_time(v, data->tsc); diff --git a/xen/include/asm-x86/hvm/vpt.h b/xen/include/asm-x86/hvm/vpt.h index 7868404426..78c7b536d4 100644 --- a/xen/include/asm-x86/hvm/vpt.h +++ b/xen/include/asm-x86/hvm/vpt.h @@ -66,7 +66,7 @@ struct periodic_time { u64 last_plt_gtime; /* platform time when last IRQ is injected */ struct timer timer; /* ac_timer */ time_cb *cb; - void *priv; /* ponit back to platform time source */ + void *priv; /* point back to platform time source */ }; @@ -76,6 +76,8 @@ struct periodic_time { typedef struct PITState { /* Hardware state */ struct hvm_hw_pit hw; + /* Last time the counters read zero, for calcuating counter reads */ + int64_t count_load_time[3]; /* irq handling */ struct periodic_time pt[3]; } PITState; diff --git a/xen/include/public/hvm/save.h b/xen/include/public/hvm/save.h index 48dfc187f0..c17075af72 100644 --- a/xen/include/public/hvm/save.h +++ b/xen/include/public/hvm/save.h @@ -140,13 +140,10 @@ struct hvm_hw_cpu { uint64_t sysenter_esp; uint64_t sysenter_eip; - /* msr for em64t */ + /* MSRs */ uint64_t shadow_gs; uint64_t flags; - - /* same size as VMX_MSR_COUNT */ uint64_t msr_items[6]; - uint64_t vmxassist_enabled; /* guest's idea of what rdtsc() would return */ uint64_t tsc; @@ -155,32 +152,6 @@ struct hvm_hw_cpu { DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_cpu); -/* - * PIT - */ - -struct hvm_hw_pit { - struct hvm_hw_pit_channel { - int64_t count_load_time; - uint32_t count; /* can be 65536 */ - uint16_t latched_count; - uint8_t count_latched; - uint8_t status_latched; - uint8_t status; - uint8_t read_state; - uint8_t write_state; - uint8_t write_latch; - uint8_t rw_mode; - uint8_t mode; - uint8_t bcd; /* not supported */ - uint8_t gate; /* timer start */ - } channels[3]; /* 3 x 24 bytes */ - uint32_t speaker_data_on; -}; - -DECLARE_HVM_SAVE_TYPE(PIT, 3, struct hvm_hw_pit); - - /* * PIC */ @@ -233,7 +204,7 @@ struct hvm_hw_vpic { uint8_t int_output; }; -DECLARE_HVM_SAVE_TYPE(PIC, 4, struct hvm_hw_vpic); +DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic); /* @@ -275,7 +246,27 @@ struct hvm_hw_vioapic { } redirtbl[VIOAPIC_NUM_PINS]; }; -DECLARE_HVM_SAVE_TYPE(IOAPIC, 5, struct hvm_hw_vioapic); +DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic); + + +/* + * LAPIC + */ + +struct hvm_hw_lapic { + uint64_t apic_base_msr; + uint32_t disabled; /* VLAPIC_xx_DISABLED */ + uint32_t timer_divisor; +}; + +DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic); + +struct hvm_hw_lapic_regs { + /* A 4k page of register state */ + uint8_t data[0x400]; +}; + +DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs); /* @@ -344,26 +335,32 @@ struct hvm_hw_irq { u8 round_robin_prev_vcpu; }; -DECLARE_HVM_SAVE_TYPE(IRQ, 6, struct hvm_hw_irq); - -/* - * LAPIC - */ +DECLARE_HVM_SAVE_TYPE(IRQ, 7, struct hvm_hw_irq); -struct hvm_hw_lapic { - uint64_t apic_base_msr; - uint32_t disabled; /* VLAPIC_xx_DISABLED */ - uint32_t timer_divisor; -}; -DECLARE_HVM_SAVE_TYPE(LAPIC, 7, struct hvm_hw_lapic); +/* + * PIT + */ -struct hvm_hw_lapic_regs { - /* A 4k page of register state */ - uint8_t data[0x400]; +struct hvm_hw_pit { + struct hvm_hw_pit_channel { + uint32_t count; /* can be 65536 */ + uint16_t latched_count; + uint8_t count_latched; + uint8_t status_latched; + uint8_t status; + uint8_t read_state; + uint8_t write_state; + uint8_t write_latch; + uint8_t rw_mode; + uint8_t mode; + uint8_t bcd; /* not supported */ + uint8_t gate; /* timer start */ + } channels[3]; /* 3 x 16 bytes */ + uint32_t speaker_data_on; }; -DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 8, struct hvm_hw_lapic_regs); +DECLARE_HVM_SAVE_TYPE(PIT, 8, struct hvm_hw_pit); /*